
#define LOG_TAG "RPP"
/*
 * Copyright (c) 2016-2020, Chengdu RST technology co., ltd
 *
 * Change Logs:
 * Date           Author       Notes
 * 2020-12-14     shijiabao       the first version
 */

/* 数据帧组成  */
/* 标志位（1B） 包类型（1B） 包长度（2B） 消息类型（1B） 数据（0~2042B）  标志位（1B） */
#include <COMMON_HEADER/common_header.h>

/*
 * 数据帧 标志位宏
 * DATA_FRAME_FRIST_FLAG                     首标志位
 * DATA_FRAME_TAIL_FLAG                      尾位置位
 */
#define DATA_FRAME_FRIST_FLAG                         0xFF
#define DATA_FRAME_TAIL_FLAG                          0xFF

/*
 * 数据帧 包类型宏
 * DATA_FRAME_INVALID_INSTRUCTION            无效指令
 * DATA_FRAME_DEVICE_REGISTRATION            设备注册
 * DATA_FRAME_DEVICE_LOGOFF                  设备注销
 * DATA_FRAME_HEARTBEAT                      心跳包
 * DATA_FRAME_DATA_PACKET                    数据包
 * DATA_FRAME_DATA_PACKET_CONTINUE           续传数据包
 * DATA_FRAME_ANALOG_INPUT                   模拟采集数据
 *
 * DATA_FRAME_DEVICE_REBOOT                  设备重启
 * DATA_FRAME_RETURN_TO_FACTORY              恢复出厂设置
 * DATA_FRAME_ANALOG_OUTPUT                  模拟输出控制
 *
 * DATA_FRAME_PARAM_QUERY                    参数查询
 * DATA_FRAME_PARAM_SETTING                  参数设置
 * DATA_FRAME_LOG_QUERY                      日志查询
 *
 * DATA_FRAME_UPGRADE_NOTICE                 升级通知
 * DATA_FRAME_UPGRADE_DATA                   固件数据传输
 */
#define DATA_FRAME_INVALID_INSTRUCTION            0x00
#define DATA_FRAME_DEVICE_REGISTRATION            0x01
#define DATA_FRAME_DEVICE_LOGOFF                  0x02
#define DATA_FRAME_HEARTBEAT                      0x03
#define DATA_FRAME_DATA_PACKET                    0x04
#define DATA_FRAME_DATA_PACKET_CONTINUE           0x05
#define DATA_FRAME_ANALOG_INPUT                   0x06

#define DATA_FRAME_DEVICE_REBOOT                  0x40
#define DATA_FRAME_RETURN_TO_FACTORY              0x41
#define DATA_FRAME_ANALOG_OUTPUT                  0x50

#define DATA_FRAME_PARAM_QUERY                    0x80
#define DATA_FRAME_PARAM_SETTING                  0x81
#define DATA_FRAME_LOG_QUERY                      0x82

#define DATA_FRAME_UPGRADE_NOTICE                 0xC0
#define DATA_FRAME_UPGRADE_DATA                   0xC1

/*
 * 数据帧 消息类型
 * DATA_FRAME_REQUEST                       请求
 * DATA_FRAME_ANSWER                        应答
 */
#define DATA_FRAME_REQUEST                         0x01
#define DATA_FRAME_ANSWER                          0x02

/* 定义数据帧数组 */
char data_packet[2048] = {0};
/* 设备编号 */
char device_number[8] = {'1','2','3','4','5','6','7','8'};
/* 私有协议心跳内容 */
char private_heartbeat[10] = {'1','2','3','4','5','6','7','8','9','a'};
/* 传输的数据内容  */
char data[4] = {'t','e','s','t'};

/**
 *  标志位（1B） 包类型（1B） 包长度（2B） 消息类型（1B） 数据（0~2042B）  标志位（1B）
 *  函数功能：根据私有协议创建一个完整的数据帧(指令型)
 *
 * @param packet_type    数据帧类型
 *        data_type      消息类型
 *        *data          核心数据的数组指针，单个数据帧核心数据的最大为2042B
 * @return data_packet   用于保存单个数据帧的数组指针，大小定义应为2KB
 */
static void data_packet_create_instruct(uint8_t packet_type, uint8_t data_type)
{
    /* 存放数据位数的变量 */
    uint8_t packet_size = 0;
    /* 清空数据帧数组 */
    memset(data_packet,'0',sizeof(data_packet));
    /* 放置标志位 */
    data_packet[0] = DATA_FRAME_FRIST_FLAG;
    /* 放置数据帧类型 */
    data_packet[1] = packet_type;
    /* 放置消息类型 */
    data_packet[4] = data_type;
    packet_size += 5;
    /* 放置尾部标志位 */
    data_packet[packet_size] = DATA_FRAME_TAIL_FLAG;
    /* 放置数据帧大小(高位) */
    data_packet[2] = ((packet_size+1) >> 8) ;
    /* 放置数据帧大小(低位) */
    data_packet[3] = ((packet_size+1) & 0xff);
}

/**
 *  标志位（1B） 包类型（1B） 包长度（2B） 消息类型（1B） 数据（0~2042B）  标志位（1B）
 *  函数功能：根据私有协议创建一个完整的数据帧(数据传输型)
 *
 * @param packet_type    数据帧类型
 *        data_type      消息类型
 *        *data          核心数据的数组指针，单个数据帧核心数据的最大为2042B
 * @return data_packet   用于保存单个数据帧的数组指针，大小定义应为2KB
 */
static void data_packet_create_data(uint8_t packet_type, uint8_t data_type, char *data)
{
    /* 存放数据位数的变量 */
    uint8_t packet_size = 0;
    /* 清空数据帧数组 */
    memset(data_packet,'0',sizeof(data_packet));
    /* 放置标志位 */
    data_packet[0] = DATA_FRAME_FRIST_FLAG;
    /* 放置数据帧类型 */
    data_packet[1] = packet_type;
    /* 放置消息类型 */
    data_packet[4] = data_type;
    /* 放置核心数据 */
    rt_kprintf("data size:%d\n",sizeof(data));
    for(int i = 0; i<sizeof(data); i++)
    {
       data_packet[5+i] = data[i];
       packet_size = i;
    }
    packet_size += 5;
    /* 放置尾部标志位 */
    data_packet[packet_size+1] = DATA_FRAME_TAIL_FLAG;
    /* 放置数据帧大小(高位) */
    data_packet[2] = ((packet_size+2) >> 8) ;
    /* 放置数据帧大小(低位) */
    data_packet[3] = ((packet_size+2) & 0xff);
}
void data_packet_create_test(void)
{
    uint8_t packet_type = 0x01;
    uint8_t data_type = 0x01;
    data_packet_create_data(packet_type,data_type, data);
    rt_kprintf("data packet print test:\n");
    for(int i = 0;i<sizeof(data_packet);i++)
    {
        rt_kprintf("%x ",data_packet[i]);
    }
}

/**
  *  无效指令
  *  函数功能：回复告知上位机这是一条无效指令(回复)
 */
void data_packet_invialid_instruction(void)
{
    data_packet_create_instruct(DATA_FRAME_INVALID_INSTRUCTION, DATA_FRAME_ANSWER);
}

/**
  *  设备注册
  *  函数功能：设备注册指令
  *  将会在数据中发送设备的编号
 */
void data_packet_device_registration_instruction(void)
{
    data_packet_create_data(DATA_FRAME_DEVICE_REGISTRATION, DATA_FRAME_REQUEST,device_number);
}

/**
  *  设备注销
  *  函数功能：设备注销下线指令
  *  将会在数据中发送设备的编号
 */
void data_packet_device_logoff_instruction(void)
{
    data_packet_create_data(DATA_FRAME_DEVICE_LOGOFF, DATA_FRAME_REQUEST,device_number);
}

/**
  *  心跳包
  *  函数功能：发送到上位机心跳包
  *  将会在数据中发送心跳内容
 */
void data_packet_heartbeat_instruction(void)
{
    data_packet_create_data(DATA_FRAME_HEARTBEAT, DATA_FRAME_REQUEST,private_heartbeat);
}

/**
  *  数据包发送
  *  函数功能：发送到上位机数据采集包
  *  将会在数据中发送采集到的数据内容
 */
void data_packet_data_upload_instruction(void)
{
    data_packet_create_data(DATA_FRAME_DATA_PACKET, DATA_FRAME_REQUEST,data);
}

/**
  *  续传数据包发送
  *  函数功能：发送到上位机数据采集包
  *  将会在数据中发送存储在本地的数据内容
 */
void data_packet_data_upload_continue_instruction()
{
    data_packet_create_data(DATA_FRAME_DATA_PACKET_CONTINUE, DATA_FRAME_REQUEST,data);
}

/**
  *  模拟数据采集数据包发送
  *  函数功能：发送到上位机数据采集包
  *  将会在数据中发送存储在本地的数据内容
 */
void data_packet_analog_data_upload_instruction(void)
{
    data_packet_create_data(DATA_FRAME_ANALOG_INPUT, DATA_FRAME_REQUEST,data);
}

/**
  *  设备重启
  *  函数功能：下发控制指令控制设备重启(回复)
 */
void data_packet_device_reboot_instruction(void)
{
    data_packet_create_instruct(DATA_FRAME_DEVICE_REBOOT, DATA_FRAME_ANSWER);
}

/**
  *  设备恢复出厂设置
  *  函数功能：下发控制指令控制设备恢复出厂设置(回复)
 */
void data_packet_return_to_factory_instruction(void)
{
    data_packet_create_instruct(DATA_FRAME_RETURN_TO_FACTORY, DATA_FRAME_ANSWER);
}

/**
  *  模拟输出控制
  *  函数功能：控制下位机模拟输出(回复)
 */
void data_packet_analog_output_contonl_instruction(void)
{
    data_packet_create_instruct(DATA_FRAME_ANALOG_OUTPUT, DATA_FRAME_ANSWER);
}

/**
  *  参数查询
  *  函数功能：查询下位机参数配置(回复)
 */
void data_packet_param_query_instruction(void)
{
    data_packet_create_instruct(DATA_FRAME_PARAM_QUERY, DATA_FRAME_ANSWER);
}

/**
  *  设置参数
  *  函数功能：查询下位机参数配置(回复)
 */
void data_packet_param_setting_instruction(void)
{
    data_packet_create_instruct(DATA_FRAME_PARAM_SETTING, DATA_FRAME_ANSWER);
}

/**
  *  日志查询
  *  函数功能：查询下位机参数配置(回复)
 */
void data_packet_log_query_instruction(void)
{
    data_packet_create_data(DATA_FRAME_LOG_QUERY, DATA_FRAME_ANSWER,data);
}

/**
  *  设备升级
  *  函数功能：通知下位机进行设备升级(回复)
 */
void data_packet_upgrade_notice_instruction(void)
{
    data_packet_create_instruct(DATA_FRAME_UPGRADE_NOTICE, DATA_FRAME_ANSWER);
}

/**
  *  设备升级
  *  函数功能：接收设备升级固件数据(回复)
 */
void data_packet_upgrade_data_instruction(void)
{
    data_packet_create_instruct(DATA_FRAME_UPGRADE_DATA, DATA_FRAME_ANSWER);
}

